package pl.edu.mimuw.irs.core.model.analysis.util;

import java.util.Collection;
import java.util.HashMap;
import java.util.Random;
import java.util.TreeSet;

import pl.edu.mimuw.irs.core.model.analysis.atomic.AnalysisTransition;
import pl.edu.mimuw.irs.core.model.petrinet.Transition;

public class TransitionsRandomizer {

	// *** Attributes
	
	private Random random;
	private double range;
	public HashMap<Double, Transition> map; // TODO : private
	private TreeSet<Double> treeSet;

	// *** Constructors
	
	public TransitionsRandomizer(Collection<Transition> transitions) {
		random = new Random();
		range = 0d;
		map = new HashMap<Double, Transition>();
		treeSet = new TreeSet<Double>();
		
		/* 
		 * Building tree of doubles indicating start of the range. All
		 * standard trasitions use one unit in this scale. AnalysisTransitions
		 * can differ and use the analysisTransition.getChance() range.
		 */
		for (Transition transition : transitions) {
			map.put(range, transition);
			treeSet.add(range);
			if (transition instanceof AnalysisTransition) {
				AnalysisTransition analysisTransition = (AnalysisTransition) transition;
				range += analysisTransition.getChance();
			} else {
				range += 1;
			}
		}
	}
	
	// *** Methods
	
	public Transition getRandom() {
		Transition randomTransition = null;
		
		/*
		 * Tree is built - we can now get random value and return corresponding
		 * Transition.
		 */
		Double randomValue = random.nextDouble() * range;
		/* 
		 * We will treat the 0 as the last because of the way we get
		 * values from the tree (get strictly lower).
		 */
		if (randomValue == 0) randomValue = range;
		Double ticket = treeSet.lower(randomValue);
		randomTransition = map.get(ticket);
		
		return randomTransition;
	}
	
	@Override
	public String toString() {
		return "Randomizer" + map;
	}
}
